package com.hex.ds.hdrs.cron.service;

import cn.hutool.core.util.StrUtil;
import com.hex.bigdata.hbda.base.Page;
import com.hex.bigdata.hbda.utils.StringUtils;
import com.hex.ds.hdrs.agent.po.AgentConf;
import com.hex.ds.hdrs.agent.service.AgentConfService;
import com.hex.ds.hdrs.app.po.AppConf;
import com.hex.ds.hdrs.app.service.impl.AppConfService;
import com.hex.ds.hdrs.common.constant.Const;
import com.hex.ds.hdrs.common.utils.BaseUtil;
import com.hex.ds.hdrs.common.utils.ListUtil;
import com.hex.ds.hdrs.common.utils.MapUtil;
import com.hex.ds.hdrs.cron.dao.CronTaskDao;
import com.hex.ds.hdrs.cron.dto.CronTaskDto;
import com.hex.ds.hdrs.cron.po.CronTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Package: com.hex.ds.hdrs.cron.service
 * @ClassName CronTaskService
 * @Description: 定时任务 服务层
 * @Author: jd.chen
 * @Date 2021/7/8 18:00
 * @Version v1.0
 **/
@Service
@Slf4j
public class CronTaskService {

    @Autowired
    private CronTaskDao cronTaskDao;

    @Autowired
    private AppConfService appConfService;

    @Autowired
    private AgentConfService agentConfService;

    /**
     * @Method: insertCronTask
     * @Param: [cronTask]
     * @Return: void
     * @Description： 新增定时任务
     * @Author： jd.chen
     * @Date： 2021/7/8 17:11
     * @Version： V1.0
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void insertCronTask(CronTask cronTask) {
        this.cronTaskDao.insertCronTask(cronTask);
    }

    /**
     * 分页查询
     *
     * @param cronTaskDto
     * @param page
     * @return
     */
    public List<CronTask> qryJobDefPage(CronTaskDto cronTaskDto, Page page) {
        log.debug("【CronTaskService.qryJobDefPage】参数cronTaskDto: {}", cronTaskDto);
        CronTask cronTask = new CronTask();
        cronTask.setTaskCode(cronTaskDto.getTaskCode());
        cronTask.setTaskName(cronTaskDto.getTaskName());
        cronTask.setCronExpress(cronTaskDto.getCronExpress());
        cronTask.setAppointAgentCode(cronTaskDto.getAppointAgentCode());
        cronTask.setBatchTag(cronTaskDto.getBatchTag());
        if (StringUtils.isNotBlank(cronTaskDto.getAppCode())) {
            cronTask.setAppCode(cronTaskDto.getAppCode());
        }
        cronTask.setExecStatus(cronTaskDto.getExecStatus());
        Map map = MapUtil.convertObjToMap(cronTask);
        if (!ListUtil.isEmpty(cronTaskDto.getStartTime())) {
            cronTaskDto.setStartTimeStart(this.setDateTimeSeparator(cronTaskDto.getStartTime().get(0)));
            cronTaskDto.setStartTimeEnd(this.setDateTimeSeparator(cronTaskDto.getStartTime().get(1)));
            map.put("startTimeStart", cronTaskDto.getStartTimeStart());
            map.put("startTimeEnd", cronTaskDto.getStartTimeEnd());
        }
        if (!ListUtil.isEmpty(cronTaskDto.getEndTime())) {
            cronTaskDto.setEndTimeStart(this.setDateTimeSeparator(cronTaskDto.getEndTime().get(0)));
            cronTaskDto.setEndTimeEnd(this.setDateTimeSeparator(cronTaskDto.getEndTime().get(1)));
            map.put("endTimeStart", cronTaskDto.getEndTimeStart());
            map.put("endTimeEnd", cronTaskDto.getEndTimeEnd());
        }
        if (StrUtil.isNotBlank(cronTaskDto.getTaskCodes()) && StrUtil.containsAny(cronTaskDto.getTaskCodes(), ",", "，")) {
            List<String> taskCodeList = Arrays.asList(cronTaskDto.getTaskCodes().toUpperCase().replace("，", ",").split(","));
            map.put("taskCodeList", taskCodeList);
        }else if (StrUtil.isNotBlank(cronTaskDto.getTaskCodes())){
            map.put("taskCodeFuzzy", cronTaskDto.getTaskCodes().toUpperCase());
        }
        List<CronTask> cronTaskList = this.cronTaskDao.qryJobDefPage(map, page);
        for (CronTask task : cronTaskList) {
           if (StrUtil.isNotBlank(task.getAppointAgentCode())){
               AgentConf agentConf = agentConfService.qryAgentConfByAgentCode(task.getAppointAgentCode());
               if (agentConf != null){
                   task.setAppointAgentName(agentConf.getAgentName());
               }
           }
        }
        return cronTaskList;
    }

    /**
     * 查询TimeTask集合(不分页)
     *
     * @param cronTask
     * @return
     */
    public List<CronTask> qryTaskList(CronTask cronTask) {
        Map map = MapUtil.convertObjToMap(cronTask);
        return this.cronTaskDao.qryTaskList(map);
    }

    public List<CronTask> qryTaskList(Map paramMap) {
        return this.cronTaskDao.qryTaskList(paramMap);
    }

    public List<CronTask> qryTaskList(String appCode, String bizDate, List<String> taskCodeList) {
        Map paramMap = new HashMap(16);
        paramMap.put("appCode", appCode);
        paramMap.put("bizDate", bizDate);
        paramMap.put("taskCodeList", taskCodeList);
        return this.cronTaskDao.qryTaskList(paramMap);
    }

    public List<CronTask> qryTaskListByTaskStatus(String appCode, String taskStatus, List<String> taskCodeList) {
        Map paramMap = new HashMap(16);
        paramMap.put("appCode", appCode);
        paramMap.put("execStatus", taskStatus);
        paramMap.put("taskCodeList", taskCodeList);
        return this.cronTaskDao.qryTaskList(paramMap);
    }

    /**
     * 获取某一日定时任务运行状态数值
     *
     * @param appCode
     * @param bizDate
     * @return
     */
    public List<Map> countGroupByExecStatus(String appCode, String bizDate) {
        Map map = new HashMap();
        map.put("appCode", appCode);
        map.put("bizDate", bizDate);
        return this.cronTaskDao.countGroupByExecStatus(map);
    }

    public List<Map> countGroupByExecStatus(String appCode) {
        Map map = new HashMap();
        map.put("appCode", appCode);
        return this.cronTaskDao.countGroupByExecStatus(map);
    }

    public List<Map> countExecStatusByUser(String bizDate) {
        String username = BaseUtil.getUserId();
        Map paramMap = new HashMap(16);

        List<AppConf> appConfList = this.appConfService.findAppByCurrentUser(username);
        List<String> appCodeList = appConfList.stream().map(AppConf::getAppCode).collect(Collectors.toList());
        paramMap.put("appCodeList", appCodeList);
        if (StringUtils.isNotBlank(bizDate)) {
            paramMap.put("bizDate", bizDate);
        }
        if (StringUtils.isNotEmpty(username)&&!Const.APP_ADMIN.equals(username)) {
            paramMap.put("username", username);
        }
        return this.cronTaskDao.countGroupByExecStatus(paramMap);
    }

    /**
     * 获取当前用户一段时间内的执行情况
     *
     * @param appCode
     * @param startTime
     * @return
     */
    public List getTaskListByCruuentApp(String appCode, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentApp】appCode: {}", appCode);
        Map map = new HashMap();
        map.put("appCode", appCode);
        map.put("startTime", startTime);
        return this.cronTaskDao.getTaskListByCruuentApp(map);
    }
    public List getTaskListByCruuentApp2(String appCode, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentApp】appCode: {}", appCode);
        Map map = new HashMap();
        map.put("appCode", appCode);
        map.put("startTime", startTime);
        return this.cronTaskDao.getTaskListByCruuentApp2(map);
    }
    public List getTaskListByCruuentApp3(String appCode, String startTime) {
        log.debug("【PeriodJobService.getTaskListByCruuentApp】appCode: {}", appCode);
        Map map = new HashMap();
        map.put("appCode", appCode);
        map.put("startTime", startTime);
        return this.cronTaskDao.getTaskListByCruuentApp3(map);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteByCode(String taskCode) {
        this.cronTaskDao.deleteByCode(taskCode);
    }

    public Integer countTask(Map paramMap) {
        return this.cronTaskDao.countTask(paramMap);
    }

    public Integer countTask(String appCode, String bizDate, String execStatus) {
        Map paramMap = new HashMap(16);
        paramMap.put("appCode", appCode);
        paramMap.put("execStatus", execStatus);
        paramMap.put("bizDate", bizDate);
        return this.cronTaskDao.countTask(paramMap);
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateCronTask(CronTask cronTask) {
        this.cronTaskDao.updateCronTask(cronTask);
    }

    /**
     * @Method: delTaskByDate <br>
     * @Param: [map] <br>
     * @Return: void <br>
     * @Description：根据时间删除数据<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/3 16:02 <br>
     * @Version： V1.0<br>
     */
    public void delTaskByDate(Map map) {
        this.cronTaskDao.delTaskByDate(map);
    }

    /**
     * @Method: reductionCronTask <br>
     * @Param: [bitchId] <br>
     * @Return: void <br>
     * @Description：还原数据<br>
     * @Author： gc.zuo<br>
     * @Date： 2021/6/3 16:02 <br>
     * @Version： V1.0<br>
     */
    public void reductionCronTask(String bitchId) {
        this.cronTaskDao.reductionCronTask(bitchId);
    }

    private String setDateTimeSeparator(String dateTime){
        String result = "";
        if (StringUtils.isNotBlank(dateTime) && dateTime.length() == 18){
            StringBuilder builder = new StringBuilder();
            builder.append(dateTime.substring(0,10)).append(" ").append(dateTime.substring(10,18));
            result = builder.toString();
        }
        return result;
    }

    /**
     * @Method: selectUnionCountByTaskStatus
     * @Param: [paramMap]
     * @Return: java.util.List<java.util.Map>
     * @Description: 定时任务状态的任务数量查询
     * @Author: ji.tang
     * @Date: 2022/6/16 16:45
     * @Version: V1.0
     */
    public List<Map> selectUnionCountByTaskStatus(Map paramMap) {
        return this.cronTaskDao.selectUnionCountByTaskStatus(paramMap);
    }
}
